//// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
//package com.linqingying.gitcode.pullrequest.ui.toolwindow.model
//
//import com.intellij.collaboration.util.ComputedResult
//import com.intellij.openapi.project.Project
//import com.intellij.openapi.util.Disposer
//import com.intellij.platform.util.coroutines.childScope
//import com.intellij.util.io.await
//import kotlinx.coroutines.CancellationException
//import kotlinx.coroutines.CoroutineScope
//import kotlinx.coroutines.channels.awaitClose
//import kotlinx.coroutines.flow.*
//import kotlinx.coroutines.launch
//import org.jetbrains.annotations.ApiStatus
//import com.linqingying.gitcode.api.data.pullrequest.GCPullRequest
//import com.linqingying.gitcode.pullrequest.data.GCPRDataContext
//import com.linqingying.gitcode.pullrequest.data.GCPRIdentifier
//import com.linqingying.gitcode.pullrequest.data.provider.GCPRDataProvider
//import com.linqingying.gitcode.pullrequest.ui.GCApiLoadingErrorHandler
//import com.linqingying.gitcode.pullrequest.ui.details.model.GCPRDetailsLoadingViewModel
//import com.linqingying.gitcode.pullrequest.ui.details.model.impl.GCPRDetailsViewModel
//import com.linqingying.gitcode.pullrequest.ui.details.model.impl.GCPRDetailsViewModelImpl
//import java.util.concurrent.CompletableFuture
//
//@ApiStatus.Experimental
//class GCPRInfoViewModel internal constructor(
//  private val project: Project,
//  parentCs: CoroutineScope,
//  private val dataContext: GCPRDataContext,
//  private val dataProvider: GCPRDataProvider
//) : GCPRDetailsLoadingViewModel {
//  private val cs = parentCs.childScope()
//
//  val pullRequest: GCPRIdentifier = dataProvider.id
//  val pullRequestUrl: String? get() = dataProvider.detailsData.loadedDetails?.url
//
//  override val detailsVm: StateFlow<ComputedResult<GCPRDetailsViewModel>>
//
//  init {
//    val detailsRequestsFlow: Flow<CompletableFuture<GCPullRequest>> = callbackFlow {
//      val listenerDisposable = Disposer.newDisposable()
//      dataProvider.detailsData.loadDetails(listenerDisposable) {
//        launch { send(it) }
//      }
//      awaitClose {
//        Disposer.dispose(listenerDisposable)
//      }
//    }
//
//    detailsVm = channelFlow<ComputedResult<GCPRDetailsViewModel>> {
//      var vm: GCPRDetailsViewModelImpl? = null
//      detailsRequestsFlow.collectLatest {
//        if (vm == null) {
//          send(ComputedResult.loading())
//        }
//
//        vm?.isUpdating?.value = true
//        val toSend = try {
//          val details = it.await()
//          val currentVm = vm
//          if (currentVm == null) {
//            val newVm = GCPRDetailsViewModelImpl(project, cs.childScope(), dataContext, dataProvider, details)
//            vm = newVm
//            ComputedResult.success(newVm)
//          }
//          else {
//            currentVm.update(details)
//            null
//          }
//        }
//        catch (ce: CancellationException) {
//          vm?.destroy()
//          vm = null
//          ComputedResult.loading()
//        }
//        catch (e: Throwable) {
//          vm?.destroy()
//          vm = null
//          ComputedResult.failure(e)
//        }
//        finally {
//          vm?.isUpdating?.value = false
//        }
//        if (toSend != null) {
//          send(toSend)
//        }
//      }
//
//    }.stateIn(cs, SharingStarted.Lazily, ComputedResult.loading())
//  }
//
//  val detailsLoadingErrorHandler: GCApiLoadingErrorHandler = GCApiLoadingErrorHandler(project, dataContext.securityService.account) {
//    dataProvider.detailsData.reloadDetails()
//  }
//
//  override fun requestReload() {
//    dataProvider.detailsData.reloadDetails()
//    dataProvider.stateData.reloadMergeabilityState()
//    dataProvider.reviewData.resetPendingReview()
//    dataProvider.reviewData.resetReviewThreads()
//    dataProvider.changesData.reloadChanges()
//    dataProvider.viewedStateData.reset()
//  }
//}
